package com.kylin.core.payment.web.facade.impl;

import com.kylin.core.common.web.facade.AbstractFacade;
import com.kylin.domain.payment.aggregate.PaymentProvider;
import com.kylin.domain.payment.command.PaymentNotifyCommand;
import com.kylin.domain.user.vo.WechatUserInfoVO;
import com.kylin.payment.api.dto.req.PaymentReqDTO;
import com.kylin.payment.api.dto.req.RefundReqDTO;
import com.kylin.payment.api.dto.resp.PaymentRespDTO;
import com.kylin.payment.api.dto.resp.RefundRespDTO;
import com.kylin.payment.api.web.facade.PaymentPlatformFacade;
import com.kylin.shared.common.ResponseWrapper;
import com.kylin.shared.common.anno.ArgsValid;
import com.kylin.shared.enums.ResultCodeEnum;
import com.lly835.bestpay.enums.BestPayPlatformEnum;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.*;
import com.lly835.bestpay.service.BestPayService;
import com.lly835.bestpay.utils.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

/**
 * 支付功能实现
 * @author Damon S.
 * @version v1.0.1
 * @date 2020年01月15日 20:52
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "微信支付接口")
public class PaymentPlatformFacadeImpl extends AbstractFacade implements PaymentPlatformFacade {

    private final BestPayService bestPayService;
    private final PaymentProvider paymentProvider;

    @ArgsValid
    @Override
    @ApiOperation(value = "订单支付", notes = "微信小程序支付")
    public ResponseWrapper<PaymentRespDTO> pay(PaymentReqDTO req) {
        WechatUserInfoVO userInfo = super.getWxUserInfo();
        if (WechatUserInfoVO.EMPTY.equals(userInfo)) {
            return new ResponseWrapper<>(ResultCodeEnum.USER_NOT_EXIST);
        }
        PayRequest payRequest = new PayRequest();
        payRequest.setOpenid(userInfo.getOpenId());
        payRequest.setOrderAmount(Double.parseDouble(req.getAmount()));
        payRequest.setOrderId(req.getOrderNo());
//        payRequest.setOrderName(req.getOrderName());
        payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_MINI);
        log.info("【发起支付】request={}", JsonUtil.toJson(payRequest));
        PayResponse payResponse = bestPayService.pay(payRequest);
        log.info("【发起支付】response={}", JsonUtil.toJson(payResponse));
        return new ResponseWrapper<>();
    }

    @ArgsValid
    @Override
    @ApiOperation(value = "退款", notes = "微信小程序退款")
    public ResponseWrapper<RefundRespDTO> refund(RefundReqDTO req) {
        WechatUserInfoVO userInfo = super.getWxUserInfo();
        if (WechatUserInfoVO.EMPTY.equals(userInfo)) {
            return new ResponseWrapper<>(ResultCodeEnum.USER_NOT_EXIST);
        }
        RefundRequest request = new RefundRequest();
        request.setOrderId(req.getOrderNo());
        request.setPayTypeEnum(BestPayTypeEnum.WXPAY_MINI);
        request.setOrderAmount(Double.parseDouble(req.getAmount()));
        RefundResponse response = bestPayService.refund(request);
        return new ResponseWrapper<>();
    }

    @ArgsValid
    @Override
    @ApiOperation(value = "支付回调", notes = "微信小程序支付回调通知")
    public ModelAndView notify(String notifyData) {
        log.info("【异步通知】支付平台的数据request={}", notifyData);
        PayResponse response = bestPayService.asyncNotify(notifyData);
        log.info("【异步通知】处理后的数据data={}", JsonUtil.toJson(response));

        paymentProvider.notifyPayment(
                PaymentNotifyCommand.builder()
                        .orderId(response.getOrderId())
                        .build()
        );
        return new ModelAndView("pay/responeSuccessForWx");
    }

    public OrderQueryResponse payOrder(@RequestParam(required = false) String orderId,
                                       @RequestParam(required = false) String outOrderId,
                                       @RequestParam BestPayPlatformEnum platformEnum) {
        OrderQueryRequest request = new OrderQueryRequest();
        request.setPlatformEnum(platformEnum);
        request.setOrderId(orderId);
        request.setOutOrderId(outOrderId);
        return bestPayService.query(request);
    }
}
